#include<iostream>
#include<cmath>
#include<string>
#include <fstream>
#include <ctype.h>

struct Node
{
	char name [11];
	char surname [21];
	char num [13];
	Node *next;
	Node *prev;
};

Node *first = 0;
Node *any = 0;
Node *p = 0;


////////////////////////////////////////////////////////////////////////////////////
void add_addres (const Node &record){
	
	if(first == 0){
		first = new Node;
		strcpy(first->name, record.name);
		strcpy(first->surname, record.surname);
		strcpy(first->num, record.num);
		first->prev = 0;
		first->next = 0;
	}
	else
	{any = new Node;
		strcpy(any->name, record.name);
		strcpy(any->surname, record.surname);
		strcpy(any->num, record.num);
		first->prev = any;
		any->next = first;
		any->prev = 0;
		first = any;}
};

/////////////////////////////////////////////////////////////////////////////
void print(const Node *ptr){
	std::cout<<ptr->name<<'\n';
	std::cout<<ptr->surname<<'\n';
	std::cout<<ptr->num<<"\n\n";
};

//////////////////////////////////////////////////////////////////////////////////
bool del_addres (const char* num){
	p = first;
	while(p){
		if(strcmp(num, p->num) ==0){
			if(p->next && p->prev){
			p->prev->next = p->next;
			p->next->prev = p->prev;
			delete p;
			return 0;			
			}
			else if (p->next && p->prev == 0){
			p->next->prev = 0;
			first = p->next;
			delete p;
			return 0;
			}
			else if (p->next == 0 && p->prev){
				p->prev->next = 0;
				delete p;
				return 0;
			}
			else{
				delete p;
				first = 0;
				return 0;
			}
		}
		else

			p = p->next;
			
	}
	return 1;
};

/////////////////////////////////////////////////////////////////////
void find (const char *surname){
	p = first;
	while(p){
		if(strcmp(p->surname, surname) ==0){
			print(p);
			p = p->next;
		}
		else
			p = p->next;
	}
};

/////////////////////////////////////////////////////////////////
void sort(){

	bool i;
	do {
		i = 0;
		p = first;
		while(p->next){
			if(p->surname[0]>p->next->surname[0]){
				if(p->prev){
					if(p->next->next){
						p->next->prev = p->prev;
						p->prev = p->next;
						p->next->next->prev = p;
						p->next = p->prev->next;
						p->prev->next = p;
						p->prev->prev->next = p->prev;
					}
					else{
						p->prev->next = p->next;
						p->next->next = p;
						p->next->prev = p->prev;
						p->prev = p->next;
						p->next = 0;
						
					}
				}
				else{
					if(p->next->next){
						p->next->next->prev = p;
						p->prev = p->next;
						p->next = p->next->next;
						p->prev->next = p;
						p->prev->prev = 0;
					}
					else{
						p->prev = p->next;
						p->next->next = p;
						p->next = 0;
						p->prev->prev = 0;
					}
					first = p->prev;
				}
				
				i++;
			}
			else
				p = p->next;				
		}
	} while (i);
};

//////////////////////////////////////////////////////////////////////////
void SaveInFile (){
	
	std::ofstream file ("ololo.txt", std::ios::out);	
	while(p){
		file.write((const char*)p, sizeof(Node));
		/*file.write(p->name,strlen(p->name));
		file.write(p->surname,strlen(p->surname));
		file.write(p->num,strlen(p->num));*/
		p = p->next;
	}
	file.close();

}

//////////////////////////////////////////////////////////////////////////
void LoadFromFile(){
	Node record;
	first = NULL;
	std::ifstream file ("ololo.txt", std::ios::in);
	while(!file.eof()){
		file.read((char*)&record, sizeof(Node));
		add_addres(record);
		file.peek();
	}
	file.close();
}

//////////////////////////////////////////////////////////////////////////
int main(){

	char n;
	for(;;)
	{
	std::cout<< "Chose the action:\n\
1. Add note\n\
2. Delete note\n\
3. Found note\n\
4. Show all notes\n\
5. Sort all notes\n\
6. Save in file\n\
7. Load from file\n\
8. Exit\n";
		std::cin>>n;
		std::cin.sync();
		std::cout<<'\n';
		switch (n)
		{
		case '1':
			Node record;
			record.num[0] = '\0';
			record.name[0] = '\0';
			record.surname[0] = '\0';
			met1: std::cout<<"Enter the name:\n";
			std::cin.getline(record.name, sizeof(record.name));
			if(strlen(record.name) == 0)
				goto met1;
			std::cin.clear();
			std::cin.sync();
			met2: std::cout<<"Enter the surname:\n";
			std::cin.getline(record.surname, sizeof(record.surname));
			if(strlen(record.surname) == 0)
				goto met2;
			std::cin.clear();
			std::cin.sync();
			met3: std::cout<<"Enter the phone number:\n";
			std::cin.getline(record.num, sizeof(record.num));
			std::cin.sync();
			std::cin.clear();
			if(strlen(record.num) == 0)
				goto met3;
			for(int i=0;i<strlen(record.num); i++){
				if(!isdigit(record.num[i]))
					goto met3;
			}
			
			p = first;
			while(p){
				if(strcmp(record.num, p->num) == 0){
					std::cout<<"This phone number has alredy exist \n\n";
					goto met3;
				}
				else
					p = p->next;
			}

			
			add_addres(record);
			std::cout<<"Well done!!!\n\n";			
			break;

		case '2':
			p = first;
			if(p){
			char num[13];
			int ret_val;
			met4: std::cout<<"Please, enter the phone number of note, which you want to delete:\n";
			std::cin.getline(num, sizeof(num));
			if(strlen(num) ==0)
				goto met4;
			std::cin.sync();
			std::cin.clear();
			ret_val = del_addres(num);
			if(ret_val == 0)
				std::cout<<"lucker!\n";
			else
				std::cout<<"This note has not exist\n";
			}
			else
				std::cout<<"Your phonebook is empty\n";
			break;

		case '3':
			p = first;
			if(p){
				char surname[21];
				met5: std::cout<<"Please, enter the surname of note, which you want to find:\n";
				std::cin.getline(surname, sizeof(surname));
				if(strlen(surname) ==0)
				goto met5;
				std::cin.sync();
				std::cin.clear();
				std::cout<<'\n';
				find(surname);
			}
			else
				std::cout<<"Your phonebook is empty\n";
			break;
				
		case '4':
			p = first;
			if(p){
				while(p){
					print(p);
					p = p->next;
				}
			}
			else
				std::cout<<"Your phonebook is empty\n";
			break;

	
		case '5':
			
			p = first;
			if(p && p->next)
				sort();				
			else
				std::cout<<"You can sort it without my help\n";
			break;

		case '6':
			p = first;
			if(p)
				SaveInFile();						
			break;

		case '7':

			LoadFromFile();
			break;


		case '8':
			return 0;
		}
	}
}